
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int bin_bits[256];
int bin_map[256];
int bin_blank[256];

void init()
{
	
	memset(bin_bits, 0, sizeof(bin_bits));
	memset(bin_map, 0, sizeof(bin_map));
	memset(bin_blank, 0, sizeof(bin_blank));

	bin_bits['0'] = 1;
	bin_bits['1'] = 1;
	bin_bits['2'] = 1;
	bin_bits['3'] = 1;
	bin_bits['4'] = 1;
	bin_bits['5'] = 1;
	bin_bits['6'] = 1;
	bin_bits['7'] = 1;
	bin_bits['8'] = 1;
	bin_bits['9'] = 1;
	bin_bits['a'] = 1;
	bin_bits['b'] = 1;
	bin_bits['c'] = 1;
	bin_bits['d'] = 1;
	bin_bits['e'] = 1;
	bin_bits['f'] = 1;
	bin_bits['A'] = 1;
	bin_bits['B'] = 1;
	bin_bits['C'] = 1;
	bin_bits['D'] = 1;
	bin_bits['E'] = 1;
	bin_bits['F'] = 1;

	bin_map['0'] = 0x00;
	bin_map['1'] = 0x01;
	bin_map['2'] = 0x02;
	bin_map['3'] = 0x03;
	bin_map['4'] = 0x04;
	bin_map['5'] = 0x05;
	bin_map['6'] = 0x06;
	bin_map['7'] = 0x07;
	bin_map['8'] = 0x08;
	bin_map['9'] = 0x09;
	bin_map['a'] = 0x0a;
	bin_map['b'] = 0x0b;
	bin_map['c'] = 0x0c;
	bin_map['d'] = 0x0d;
	bin_map['e'] = 0x0e;
	bin_map['f'] = 0x0f;
	bin_map['A'] = 0x0A;
	bin_map['B'] = 0x0B;
	bin_map['C'] = 0x0C;
	bin_map['D'] = 0x0D;
	bin_map['E'] = 0x0E;
	bin_map['F'] = 0x0F;

	bin_blank[' '] = 1;
	bin_blank['\t'] = 1;
	bin_blank['\n'] = 1;
	bin_blank['\f'] = 1;
	bin_blank['\r'] = 1;
	
}

/*
int is_blank_char(char ch)
{
	return ch==' ' || ch=='\t' || ch=='\n' || ch=='\f' || ch=='\r';
}

int is_valid_char(char ch)
{
	return ('0'<=ch && ch<='9') || ('a'<=ch && ch<='f') || ('A'<=ch && ch<='F');
}

int bin_value(char ch)
{
	if('0'<=ch && ch<='9')
	{
		return ch - '0';
	}
	else if('a'<=ch && ch<='z')
	{
		return ch - 'a' + 0x0A;
	}
	else if('A'<=ch && ch<='Z')
	{
		return ch - 'A' + 0x0A;
	}
	else
	{
		return -1;
	}
}
*/

int hex2bin(FILE* in, FILE* out)
{
	int chs[2];
	int i;

	i = 0;
	while( (chs[i] = fgetc(in)) != EOF)
	{
		if(bin_blank[chs[i]])
		{
			continue;
		}
		else if(bin_bits[chs[i]])
		{
			if(i==0)
			{
				++i;
				continue;
			}
			else
			{
				int a = (bin_map[chs[0]]<<4) & 0xF0;
				int b = (bin_map[chs[1]]   ) & 0x0F;
				fputc( a | b , out );
				i = 0;
				continue;
			}
		}
		else
		{
			fprintf(stderr, "Invalid char: 0x%02x\n", chs[i]);
			exit(1);
		}
	}
	return 0;
}

int main(int argc, char** argv)
{
	FILE* in;
	FILE* out;

	if(argc==3)
	{
		in = fopen(argv[1], "r");
		out = fopen(argv[2], "wb");
	}
	else if(argc==1)
	{
		in = stdin;
		out = stdout;
	}
	else
	{
		fprintf(stderr, "arguments error\n");
		return 1;
	}


	init();
	hex2bin(in, out);

	return 0;
}

